package com.food.foodapi.filter;

import com.food.foodapi.utils.JwtUtil;
import com.food.foodapi.utils.RedisUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

import java.io.IOException;


@SuppressWarnings("all")
public class JwtFilter implements Filter {

    private final RedisUtil redisService;

    public JwtFilter(RedisUtil redisService) {
        this.redisService = redisService;
    }

    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String uri = httpRequest.getRequestURI();

        // 排除/api/images下的所有请求
        if (uri.startsWith("/api/images")) {
            chain.doFilter(request, response);
            return;
        }

        // 排除登录和注册接口
        if (uri.equals("/api/auth/login") || uri.equals("/api/auth/register") || uri.equals("/api/article/home/list") || uri.equals(("/api/file/upload"))) {
            // 如果是登录或注册接口，直接跳过认证
            chain.doFilter(request, response);
            return;
        }
        // 排除Options
        if (httpRequest.getMethod().equals("OPTIONS")) {
            chain.doFilter(request, response);
            return;
        }

        // 从请求头获取 Token
        String token = httpRequest.getHeader("Authorization");

        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            boolean status = JwtUtil.validateToken(token);
            System.out.println(!status);
            if (!status) {
                System.out.println("第一次验证失败！");
                // Token 无效或过期，返回错误信息
                HttpServletResponse httpResponse = (HttpServletResponse) response;
                httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); // 403 未授权
                // 设置响应内容类型为 JSON，并指定编码为 UTF-8
                httpResponse.setContentType("application/json;charset=UTF-8");
                // 设置字符编码为 UTF-8，防止中文乱码
                httpResponse.setCharacterEncoding("UTF-8");
                httpResponse.setContentType("application/json");
                String errorMessage = "{\"code\":403,\"message\": \"认证失败: Token无效或过期\"}";
                httpResponse.getWriter().write(errorMessage);
                return;

            }
            String username = JwtUtil.extractUsername(token);

            // 从 Redis 获取用户的 Token
            String storedToken = redisService.getToken(username);
            System.out.println(storedToken);

            if (storedToken != null && JwtUtil.validateToken(token, username)) {
                // Token 验证通过，继续处理请求
                // 将参数添加到请求中
                System.out.println("Token 验证通过！");
                System.out.println("username: " + username);
                HttpSession session = httpRequest.getSession();
                session.setAttribute("username", username);
                chain.doFilter(request, response);
            } else {
                // Token 无效或过期，返回错误信息
                HttpServletResponse httpResponse = (HttpServletResponse) response;
                httpResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); // 403 未授权
                // 设置响应内容类型为 JSON，并指定编码为 UTF-8
                httpResponse.setContentType("application/json;charset=UTF-8");
                // 设置字符编码为 UTF-8，防止中文乱码
                httpResponse.setCharacterEncoding("UTF-8");
                httpResponse.setContentType("application/json");
                String errorMessage = "{\"code\":403,\"message\": \"认证失败: Token无效或过期\"}";
                httpResponse.getWriter().write(errorMessage);
            }
        } else {
            // 如果没有 Token，拒绝访问
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 未授权
            // 设置响应内容类型为 JSON，并指定编码为 UTF-8
            httpResponse.setContentType("application/json;charset=UTF-8");
            // 设置字符编码为 UTF-8，防止中文乱码
            httpResponse.setCharacterEncoding("UTF-8");
            httpResponse.setContentType("application/json");
            String errorMessage = "{\"code\":401,\"message\": \"认证失败: Token不存在或格式错误\"}";
            httpResponse.getWriter().write(errorMessage);
        }
    }

    @Override
    public void destroy() {}
}
